home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr26
/
netprog.zip
/
NETPROG.TAR
/
lib
/
udpopen.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-17
|
4KB
|
130 lines
/*
* Establish a UDP socket and optionally call connect() to set up
* the server's address for future I/O.
*/
#include "netdefs.h"
#include <netinet/in.h>
#include <arpa/inet.h>
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff /* should be in <netinet/in.h> */
#endif
/*
* The following globals are available to the caller, if desired.
*/
struct sockaddr_in udp_srv_addr; /* server's Internet socket addr */
struct sockaddr_in udp_cli_addr; /* client's Internet socket addr */
struct servent udp_serv_info; /* from getservbyname() */
struct hostent udp_host_info; /* from gethostbyname() */
int /* return socket descriptor if OK, else -1 on error */
udp_open(host, service, port, dontconn)
char *host; /* name of other system to communicate with */
char *service; /* name of service being requested */
/* can be NULL, iff port > 0 */
int port; /* if == 0, nothing special - use port# of service */
/* if < 0, bind a local reserved port */
/* if > 0, it's the port# of server (host-byte-order) */
int dontconn; /* if == 0, call connect(), else don't */
{
int fd;
unsigned long inaddr;
char *host_err_str();
struct servent *sp;
struct hostent *hp;
/*
* Initialize the server's Internet address structure.
* We'll store the actual 4-byte Internet address and the
* 2-byte port# below.
*/
bzero((char *) &udp_srv_addr, sizeof(udp_srv_addr));
udp_srv_addr.sin_family = AF_INET;
if (service != NULL) {
if ( (sp = getservbyname(service, "udp")) == NULL) {
err_ret("udp_open: unknown service: %s/udp", service);
return(-1);
}
udp_serv_info = *sp; /* structure copy */
if (port > 0)
udp_srv_addr.sin_port = htons(port);
/* caller's value */
else
udp_srv_addr.sin_port = sp->s_port;
/* service's value */
} else {
if (port <= 0) {
err_ret("udp_open: must specify either service or port");
return(-1);
}
udp_srv_addr.sin_port = htons(port);
}
/*
* First try to convert the host name as a dotted-decimal number.
* Only if that fails do we call gethostbyname().
*/
if ( (inaddr = inet_addr(host)) != INADDR_NONE) {
/* it's dotted-decimal */
bcopy((char *) &inaddr, (char *) &udp_srv_addr.sin_addr,
sizeof(inaddr));
udp_host_info.h_name = NULL;
} else {
if ( (hp = gethostbyname(host)) == NULL) {
err_ret("udp_open: host name error: %s %s",
host, host_err_str());
return(-1);
}
udp_host_info = *hp; /* found it by name, structure copy */
bcopy(hp->h_addr, (char *) &udp_srv_addr.sin_addr,
hp->h_length);
}
if (port < 0)
err_quit("udp_open: reserved ports not implemeneted yet");
if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
err_ret("udp_open: can't create UDP socket");
return(-1);
}
/*
* Bind any local address for us.
*/
bzero((char *) &udp_cli_addr, sizeof(udp_cli_addr));
udp_cli_addr.sin_family = AF_INET;
udp_cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);
udp_cli_addr.sin_port = htons(0);
if (bind(fd, (struct sockaddr *) &udp_cli_addr,
sizeof(udp_cli_addr)) < 0) {
err_ret("udp_open: bind error");
close(fd);
return(-1);
}
/*
* Call connect, if desired. This is used by most caller's,
* as the peer shouldn't change. (TFTP is an exception.)
* By calling connect, the caller can call send() and recv().
*/
if (dontconn == 0) {
if (connect(fd, (struct sockaddr *) &udp_srv_addr,
sizeof(udp_srv_addr)) < 0) {
err_ret("udp_open: connect error");
return(-1);
}
}
return(fd);
}